﻿using System;
using System.Text;
using System.Net.Mail;
using System.Threading;
using SystemX.Infrastructure;

namespace SystemX
{
	public static partial class Utils
	{
		#region Send e-mail

		/// <summary>
		/// Sends a MailMessage object using the SMTP settings configged in AppSettings.
		/// You should config the following settings in Web.config or app.config.
		/// 1,AppMail.SmtpServer;
		/// 2,AppMail.SmtpUserName;
		/// 3,AppMail.SmtpPassword;
		/// 4,AppMail.SmtpServerPort;
		/// 5,AppMail.EnableSsl
		/// </summary>
		public static void SendMailMessage(MailMessage message)
		{
			if (message == null)
				throw new ArgumentNullException("message");


			SendMailMessage(
				message,
				AppSettingsHelper.Instance.GetString("AppMail.SmtpServer"),
                AppSettingsHelper.Instance.GetString("AppMail.SmtpUserName"),
				AppSettingsHelper.Instance.GetString("AppMail.SmtpPassword"),
                AppSettingsHelper.Instance.GetInt32("AppMail.SmtpServerPort"),
                 AppSettingsHelper.Instance.GetBoolean("AppMail.EnableSsl")
				);
		}
		/// <summary>
		/// Sends a MailMessage object using the SMTP settings.
		/// </summary>
		public static void SendMailMessage(MailMessage message,string smtpServer,string smtpUserName,string smtpPassword,int smtpServerPort,bool enableSsl)
		{
			if (message == null)
				throw new ArgumentNullException("message");

			try
			{
				message.IsBodyHtml = true;
				message.BodyEncoding = Encoding.UTF8;
				SmtpClient smtp = new SmtpClient(smtpServer);
				// don't send credentials if a server doesn't require it,
				// linux smtp servers don't like that 
				if (!string.IsNullOrEmpty(smtpUserName))
				{
					smtp.Credentials = new System.Net.NetworkCredential(smtpUserName, smtpPassword);
				}
				smtp.Port =smtpServerPort;
				smtp.EnableSsl = enableSsl;
				smtp.Send(message);
				OnEmailSent(message);
			}
			catch (SmtpException)
			{
				OnEmailFailed(message);
			}
			finally
			{
				// Remove the pointer to the message object so the GC can close the thread.
				message.Dispose();
				message = null;
			}
		}
		/// <summary>
		/// Sends the mail message asynchronously in another thread.
		/// You should config the following settings in Web.config or app.config.
		/// 1,AppMail.SmtpServer;
		/// 2,AppMail.SmtpUserName;
		/// 3,AppMail.SmtpPassword;
		/// 4,AppMail.SmtpServerPort;
		/// 5,AppMail.EnableSsl
		/// </summary>
		/// <param name="message">The message to send.</param>
		public static void SendMailMessageAsync(MailMessage message)
		{
			ThreadPool.QueueUserWorkItem((s) => { SendMailMessage(message); });
		}

		/// <summary>
		/// Sends the mail message asynchronously in another thread.
		/// </summary>
		/// <param name="message">The message to send.</param>
		public static void SendMailMessageAsync(MailMessage message,string smtpServer,string smtpUserName,string smtpPassword,int smtpServerPort,bool enableSsl)
		{
			ThreadPool.QueueUserWorkItem((s) => { SendMailMessage(message,smtpServer,smtpUserName,smtpPassword,smtpServerPort,enableSsl); });
		}


		/// <summary>
		/// Occurs after an e-mail has been sent. The sender is the MailMessage object.
		/// </summary>
		public static event EventHandler<EventArgs> EmailSent;
		private static void OnEmailSent(MailMessage message)
		{
			if (EmailSent != null)
			{
				EmailSent(message, new EventArgs());
			}
		}

		/// <summary>
		/// Occurs after an e-mail has been sent. The sender is the MailMessage object.
		/// </summary>
		public static event EventHandler<EventArgs> EmailFailed;
		private static void OnEmailFailed(MailMessage message)
		{
			if (EmailFailed != null)
			{
				EmailFailed(message, new EventArgs());
			}
		}

		#endregion
	}
}
